﻿using System;
using System.Collections.Generic;
using GeoAPI.Geometries;
using YJKGridTopologyCal.Geometries.Utilities;

namespace YJKGridTopologyCal.Operation.Union
{
	public class UnionInteracting
	{
		public static IGeometry Union(IGeometry g0, IGeometry g1)
		{
			return new UnionInteracting(g0, g1).Union();
		}

		public UnionInteracting(IGeometry g0, IGeometry g1)
		{
			this._g0 = g0;
			this._g1 = g1;
			this._geomFactory = g0.Factory;
			this._interacts0 = new bool[g0.NumGeometries];
			this._interacts1 = new bool[g1.NumGeometries];
		}

		public IGeometry Union()
		{
			this.ComputeInteracting();
			IGeometry geometry = this.ExtractElements(this._g0, this._interacts0, true);
			IGeometry geometry2 = this.ExtractElements(this._g1, this._interacts1, true);
			if (!geometry.IsEmpty)
			{
				bool isEmpty = geometry2.IsEmpty;
			}
			IGeometry g = geometry.Union(geometry2);
			IGeometry g2 = this.ExtractElements(this._g0, this._interacts0, false);
			IGeometry g3 = this.ExtractElements(this._g1, this._interacts1, false);
			return GeometryCombiner.Combine(g, g2, g3);
		}

		private IGeometry BufferUnion(IGeometry g0, IGeometry g1)
		{
			return g0.Factory.CreateGeometryCollection(new IGeometry[]
			{
				g0,
				g1
			}).Buffer(0.0);
		}

		private void ComputeInteracting()
		{
			for (int i = 0; i < this._g0.NumGeometries; i++)
			{
				IGeometry geometryN = this._g0.GetGeometryN(i);
				this._interacts0[i] = this.ComputeInteracting(geometryN);
			}
		}

		private bool ComputeInteracting(IGeometry elem0)
		{
			bool result = false;
			for (int i = 0; i < this._g1.NumGeometries; i++)
			{
				bool flag = this._g1.GetGeometryN(i).EnvelopeInternal.Intersects(elem0.EnvelopeInternal);
				if (flag)
				{
					this._interacts1[i] = true;
				}
				if (flag)
				{
					result = true;
				}
			}
			return result;
		}

		private IGeometry ExtractElements(IGeometry geom, bool[] interacts, bool isInteracting)
		{
			List<IGeometry> list = new List<IGeometry>();
			for (int i = 0; i < geom.NumGeometries; i++)
			{
				IGeometry geometryN = geom.GetGeometryN(i);
				if (interacts[i] == isInteracting)
				{
					list.Add(geometryN);
				}
			}
			return this._geomFactory.BuildGeometry(list);
		}

		private readonly IGeometryFactory _geomFactory;

		private readonly IGeometry _g0;

		private readonly IGeometry _g1;

		private readonly bool[] _interacts0;

		private readonly bool[] _interacts1;
	}
}
